using System;
using System.Runtime.Serialization;

namespace SharedObjects
{
	/// <summary>
	/// Note: Log entries are highly dynamic entities, as they can get deleted/created with varying relations very quickly.
	/// Note: Thus, the entity references systems not directly, nor is it being referenced directly by any other entity.
	/// Note: this is for referential integrity, or lack thereof.
	/// </summary>
	[DataContract] public class ComputerSystemLog : EntityBase
	{
		[DataMember] public DateTime TimeStamp { get; set; }
		[DataMember] public LoggingAction Activity { get; set; }
		[DataMember] public string ModifiedItem { get; set; }
		[DataMember] public string ConnectingSystemAddress { get; set; } //the "who" of the log entry
		[DataMember] public ulong LoggingComputerSystemId { get; set; }
		[DataMember] public int DeleteLevel { get; set; } //indicates which version of a deleter was used. Required for undelete operations

		public static implicit operator ReadableComputerSystemLog(ComputerSystemLog log)
		{
			string action;
			switch (log.Activity) //translate the enum to something meaningful for the client
			{
				case LoggingAction.HackEmailAccounts:
					action = "Breached email security";
					break;
				case LoggingAction.HackBankAccounts:
					action = "Breached banking security";
					break;
				default:
					action = log.Activity.ToString();
					break;
			}
			
			if (log.IsDeleted && log.DeleteLevel > 5)
				return new ReadableComputerSystemLog { IsDeleted = true };

			bool deletedButVisible = log.IsDeleted && log.DeleteLevel < 6;

			ReadableComputerSystemLog l = new ReadableComputerSystemLog
			{
				Activity = deletedButVisible ? "?" : action,
				ConnectingSystemAddress = deletedButVisible ? "?" : log.ConnectingSystemAddress,
				DeleteLevel = log.DeleteLevel,
				DeletionTimeStamp = log.DeletionTimeStamp,
				Id = log.Id,
				IsDeleted = log.IsDeleted,
				LoggingComputerSystemId = log.LoggingComputerSystemId,
				ModifiedItem = deletedButVisible ? "?" : log.ModifiedItem,
				TimeStamp = deletedButVisible? new DateTime() : log.TimeStamp,
			};
			return l;
		}
	}

	[DataContract] 
	public class ReadableComputerSystemLog : EntityBase
	{
		[DataMember]
		public DateTime TimeStamp { get; set; }
		[DataMember]
		public string Activity { get; set; }
		[DataMember]
		public string ModifiedItem { get; set; }
		[DataMember]
		public string ConnectingSystemAddress { get; set; }
		[DataMember]
		public ulong LoggingComputerSystemId { get; set; }
		[DataMember]
		public int DeleteLevel { get; set; }
	}

	public enum LoggingAction
	{
		Routed,			//someone routed thru this system
		Connect,		//someone connected to a system
		Bypass,			//someone bypassed a secsys
		BypassFailed,	//someone tried and failed to bypass a secsys
		Login,			//someone logged into the system interface
		Disconnect,		//someone disconnected from a system
		FileRead,		//someone read or copied a file or database record
		FileCreated,	//someone copied a file to a system
		FileDeleted,	//someone deleted a file/database record
		FileModified,	//someone altered a file/database record (applies to DataWithContent or database records only)
		FileRestored,	//someone undeleted a file
		FeatureAccess,	//someone accessed a feature
		LogDeleted,		//someone deleted a log entry
		LogRestored,	//someone undeleted a log entry
		HackEmailAccounts, //someone entered the mail system in hacked mode.
		HackBankAccounts, //someone entered the bank system in hacked mode.
	}
}